import React, { useState, useEffect } from 'react';
import { Modal, Form, Row, Col, Input, DatePicker, Card, Button, message } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import moment, { Moment } from 'moment';
import { AButton, AGrid, AGridButtonCallBackModel, ASelect, ASelectOptionType } from '@/components/SelfComp';
import { DataItem, FlagEnum, FormModalProps } from '@/types/global';
import { TradeTaskItem, CqDetailInfoFormValue } from '@/types/workbench';
import { formLayout, modalFormItemLayout, maxModalFormItemLayout, getItemValue } from '@/utils/commons';

type TradeTaskProps<T> = FormModalProps<T> & {
  testerData: DataItem[];
  developerData: DataItem[];
  tradeTaskNameData: DataItem[];
  tradeTaskList: TradeTaskItem[];
  tradeTaskTotal: number;
  flag?: FlagEnum;
  tradeTaskHandle: (handleType: string, record: TradeTaskItem | TradeTaskItem[]) => Promise<boolean>;
  taskHandleLoading: boolean;
}
// type TradeTaskPropsEx<T> = Omit<TradeTaskProps<T>, 'formData'>;

type TradeTaskFormType = {
  taskType: string;
  taskHash: string; // 
  taskId?: string; // 可能存在
  taskName: string;
  taskPhase: string;
  taskDate: Moment[];
  developer: string;
  tester: string;
  comment: string;
}

const FormItem = Form.Item;
const TextArea = Input.TextArea;
const { RangePicker } = DatePicker;
const dateFormatPattern = 'YYYY-MM-DD';

/**
   * 生成一个4位随机数
   *
   * @returns 4位随机数
   */
const randomStr = (): string => {
  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}

const columns: ColumnsType<TradeTaskItem> = [
  {
    title: '任务名称',
    dataIndex: 'taskName',
    width: 150,
    ellipsis: true
  },
  {
    title: '任务阶段',
    dataIndex: 'taskPhase',
    width: 100,
  },
  {
    title: '开始时间',
    dataIndex: 'startDate',
    width: 120
  },
  {
    title: '结束时间',
    dataIndex: 'endDate',
    width: 120
  },
  {
    title: '开发人员',
    dataIndex: 'developer',
    width: 120
  },
  {
    title: '测试人员',
    dataIndex: 'tester',
    width: 120,
    ellipsis: true
  },
  {
    title: '备注/附件CC路径',
    dataIndex: 'comment',
    width: 300,
    ellipsis: true
  }
];

/**
 * 交易分配开发任务相关窗口组件
 */
const TradeTaskModal: React.FC<TradeTaskProps<CqDetailInfoFormValue>> = (props) => {
  // 需求基础信息表单
  const [operaType, setOperaType] = useState<string>('add');
  // const [] = useState<TradeTaskItem>();
  // 交易表格勾选
  const [selectedRows, setSelectedRows] = useState<TradeTaskItem[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  // 本地交易任务列表
  const [localTradeTaskList, setLocalTradeTaskList] = useState<TradeTaskItem[]>([]);
  // 手工分页
  const [pageSize, setPageSize] = useState<number>(10);
  // const [tradeTasks, setTradeTasks] = useState<TradeTaskItem[]>([]);

  const [form] = Form.useForm<TradeTaskFormType>();

  useEffect(() => {
    console.info('TradeTaskModal.useEffect');
    // 父页面传递来的交易任务列表
    // 当传入了多个
    const { tradeTaskList } = props;
    if (tradeTaskList && tradeTaskList.length > 0) {
      setLocalTradeTaskList([...tradeTaskList]);
      // fetchTaskByPage(1, pageSize, tradeTaskList);
    }
  }, []);

  /**
   * 弹窗的确定事件，提交任务，关闭弹窗
   */
  const onOk = () => {
    // 判断表单是否有正在分配的任务
    // 没有，则判断表格是否有数据
    // 没有，则提示请先分配任务在提交
    // 有，返回父页面当前任务数量信息等
    Modal.confirm({
      title: '确定',
      content: '确定提交任务吗？请检查交易任务分配是否有错误及遗漏！',
      onOk: () => submitTradeTask()
    });
  };

  const submitTradeTask = () => {
    const { onHandlerOK } = props;
    if (onHandlerOK) {
      // 获取当前任务总数
      onHandlerOK(localTradeTaskList.length);
    }
  }

  const onCancel = () => {
    // 先清除form表单
    form.resetFields();
    const { onHandlerCancel } = props;
    if (onHandlerCancel) {
      onHandlerCancel(localTradeTaskList.length);
    }
  }

  /**
   * 点击表格中的修改按钮，反显表格数据到表单中
   */
  const modifyTaskHandler = () => {
    if (selectedRowKeys.length === 0) {
      message.warn('请先选择一条数据!');
      return;
    }
    if (selectedRowKeys.length > 1) {
      message.warn('只能选择一条数据!');
      return;
    }
    const record: TradeTaskItem = selectedRows[0];
    // console.log('modifyTaskHandler', record);
    setDataToForm(record);
  }

  /**
   * 设置表格数据到表单栏位中
   * 
   * @param record 
   */
  const setDataToForm = (record: TradeTaskItem) => {
    // 根据页面传值，将栏位赋默认值
    const { startDate, endDate, ...rest } = record;
    const taskDate = [moment(startDate, dateFormatPattern), moment(endDate, dateFormatPattern)]
    const formValue: TradeTaskFormType = {
      ...rest,
      taskDate
    }
    form.setFieldsValue({
      ...formValue
    });
    setOperaType('edit');
  }

  /**
   * 点击表格中的删除按钮
   */
  const deleteTaskHandler = () => {
    if (selectedRowKeys.length === 0) {
      message.warn('至少选择一条数据!');
      return;
    }
    // const record: TradeTaskItem = selectedRows[0];
    // console.log('deleteTaskHandler', record);
    Modal.confirm({
      title: '确认',
      content: '确定删除该任务吗',
      onOk: () => deleteTasks(selectedRows)
    });
  }

  /**
   * 删除任务
   */
  const deleteTasks = (records: TradeTaskItem[]) => {
    // 调父页面方法，删除任务
    const { tradeTaskHandle } = props;
    if (tradeTaskHandle) {
      const record = records[0];
      tradeTaskHandle('delete', record).then(res => {
        if (res) {
          // 服务器通讯通讯成功后才修改表格
          const newTradeTaskList = [
            ...localTradeTaskList
          ];
          const len = newTradeTaskList.length;
          // 按照hash查找对应条目，然后修改
          let index = -1;
          const { taskHash } = record;
          for (let i = 0; i < len; i += 1) {
            const item = newTradeTaskList[i];
            if (taskHash === item.taskHash) {
              index = i;
              break;
            }
          }
          // console.info('符合条件的数组下标为', index);
          newTradeTaskList.splice(index, 1);
          setLocalTradeTaskList([...newTradeTaskList]);
          setOperaType('add');
        }
      });
    }
  }

  /**
   * 添加或修改表单数据
   * 默认为添加，当点击了表格中的修改按钮，则反显表格数据到表单中
   */
  const addTaskToTable = () => {
    const fieldsValue = form.getFieldsValue();
    // console.info(fieldsValue);
    let { taskHash } = fieldsValue;
    const { taskDate, ...rest } = fieldsValue;
    // console.info('表单原始数据', fieldsValue, operaType);
    if (!taskHash) {
      // 添加时设置一个hash值
      taskHash = randomStr();
    }
    const values: TradeTaskItem = {
      ...rest,
      taskHash,
      startDate: taskDate[0].format(dateFormatPattern),
      endDate: taskDate[1].format(dateFormatPattern),
    };
    // 新增
    if (operaType === 'add') {
      addTask(values);
    } else if (operaType === 'edit') {
      updateTask(values);
    }
  }

  const onReset = () => {
    // 先清除form表单
    form.resetFields();
    setOperaType('add');
  }

  /**
   * 新增任务
   * @param record 表单数据
   */
  const addTask = (record: TradeTaskItem) => {
    // 调父页面方法，新增任务
    const { tradeTaskHandle } = props;
    if (tradeTaskHandle) {
      tradeTaskHandle('add', record).then(res => {
        if (res) {
          // 服务器通讯，通讯成功后才添加进表格
          const newTradeTaskList = [...localTradeTaskList];
          newTradeTaskList.push(record);
          // console.info('准备提交的数据', newTradeTaskList);
          setLocalTradeTaskList([...newTradeTaskList]);
          setOperaType('add');
          form.resetFields();
        }
      });
    }
  }

  /**
   * 修改任务
   * @param record 表单数据
   */
  const updateTask = (record: TradeTaskItem) => {
    // 调父页面方法，修改任务
    const { tradeTaskHandle } = props;
    if (tradeTaskHandle) {
      tradeTaskHandle('edit', record).then(res => {
        if (res) {
          // 服务器通讯, 通讯成功后才修改表格
          const { taskHash } = record;
          const newTradeTaskList = [...localTradeTaskList];
          // 按照hash查找对应条目，然后修改
          const len = newTradeTaskList.length;
          let index = -1;
          for (let i = 0; i < len; i += 1) {
            const item = newTradeTaskList[i];
            if (taskHash === item.taskHash) {
              index = i;
              break;
            }
          }
          // console.info('符合条件的数组下标为', index);
          newTradeTaskList.splice(index, 1, record);
          // console.info('准备提交的数据', newTradeTaskList);
          setLocalTradeTaskList([...newTradeTaskList]);
          setOperaType('add');
          form.resetFields();
        }
      });
    }
  }

  /**
   * 工具栏左边的按钮
   * @returns 按钮集合
   */
  const renderLeftButton = () => {
    const { loading } = props;
    return (
      <>
        <AButton code='editTask' pageCode='cq-trade' name='修改任务' onClick={modifyTaskHandler} loading={loading} />
        <AButton code='deleteTask' pageCode='cq-trade' name='删除任务' onClick={deleteTaskHandler} loading={loading} />
      </>
    );
  }

  /**
   * 处理按钮点击回调事件
   * @param {*} payload 数据包
   */
  const handleBtnCallBack = (callBackModel: AGridButtonCallBackModel<TradeTaskItem>) => {
    // btn 按钮
    // keys 表格勾选数组
    const { code, rows } = callBackModel;
    // console.info(keys);
    // console.info('handleBtnCallBack', rows);
    // 修改
    if (code === 'edit') {
      const { rows } = callBackModel;
      const record: TradeTaskItem = rows[0];
      setDataToForm(record);
      return;
    }
    // 删除
    if (code === 'delete') {
      // 调用删除服务，删除勾选数据
      // console.info(keys);
      deleteTasks(rows);
      return;
    }
  }

  /**
   * 表格勾选回调函数
   * @param {*} rows 表格选中数据集合
   */
  const onSelectRow = (keys: React.Key[], rows: TradeTaskItem[]) => {
    // console.info(keys);
    // console.info(rows);
    setSelectedRowKeys(keys);
    setSelectedRows(rows);
  };

  /**
   * 手动获取分页数据
   * @param {*} pageSize 每页记录条数
   * @param {*} pageNum 页码
   * @param {*} userList 用户列表数据
   */
  const fetchTaskByPage = (pageNum: number, pageSize: number, tradeList: TradeTaskItem[]) => {
    if (tradeList && tradeList.length > 0) {
      const tmpTaskList: TradeTaskItem[] = tradeList.slice((pageNum - 1) * pageSize, pageNum * pageSize);
      return tmpTaskList;
    }
    return [];
  }

  /**
   * 页码改变的回调，参数是改变后的页码及每页条数
   * @param page 改变后的页码，上送服务器端
   * @param pageSize 每页数据条数
   */
  const onPageNumAndSizeChange = (page: number, pageSize: number) => {
    console.log(page, pageSize);
    setPageSize(pageSize);
    // fetchTaskByPage(page, pageSize, localTradeTaskList);
  };

  /**
   * 任务类型栏位变化事件，根据栏位选择，给任务名称栏位赋值
   * 
   * @param value 
   * @param option 
   */
  const taskTypeOnChange = (value: string, option: ASelectOptionType | ASelectOptionType[]) => {
    // console.info(value);
    // console.info(option);
    const { tradeTaskNameData } = props;
    const taskName = getItemValue(tradeTaskNameData, value);
    form.setFieldsValue({
      taskName,
      comment: taskName
    });
  }

  /**
   * 任务阶段栏位变化事件，根据栏位选择，选择对应的时间段给任务起止栏位赋值
   * 
   * @param value 
   * @param option 
   */
  const taskPhaseOnChange = (value: string, option: ASelectOptionType | ASelectOptionType[]) => {
    // console.info(value);
    // console.info(option);
    const { formData } = props;
    if (value === 'DEV') {
      const { devStartDate, devEndDate } = formData;
      setTaskDate(devStartDate, devEndDate);
    } else if (value === 'SIT') {
      const { sitStartDate, sitEndDate } = formData;
      setTaskDate(sitStartDate, sitEndDate);
    } else if (value === 'UAT') {
      const { uatStartDate, uatEndDate } = formData;
      setTaskDate(uatStartDate, uatEndDate);
    } else {
      // 重置
      form.resetFields([
        'taskDate'
      ])
    }
  }

  const setTaskDate = (startDate: string, endDate: string) => {
    const taskDate = [moment(startDate, dateFormatPattern), moment(endDate, dateFormatPattern)]
    form.setFieldsValue({
      taskDate
    });
  }

  /**
   * 新增，修改任务时，展示任务表单
   * @returns 交易信息栏位
   */
  const getTaskContent = (props: TradeTaskProps<CqDetailInfoFormValue>) => {
    const { colon, developerData, testerData, tradeTaskNameData } = props;
    const taskPhaseData: DataItem[] = [
      {
        key: 'DEV',
        value: '开发测试'
      },
      {
        key: 'SIT',
        value: '系统集成测试'
      },
      {
        key: 'UAT',
        value: '用户验收测试'
      },
    ];
    return (
      <>
        <Row>
          <Col span={12}>
            <FormItem label='任务类型' name='taskType' {...modalFormItemLayout} colon={colon}
              rules={[
                { required: true, message: '任务类型必输' },
              ]}>
              <ASelect dataSource={tradeTaskNameData} type='1' onChange={taskTypeOnChange} />
            </FormItem>
          </Col>
          <Col span={12}>
            <FormItem label='' name='taskHash' colon={colon} hidden>
              <Input type='hidden'/>
            </FormItem>
            <FormItem label='' name='taskId' colon={colon} hidden>
              <Input type='hidden'/>
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <FormItem label='任务名称' name='taskName' {...maxModalFormItemLayout} colon={colon}
              rules={[
                { required: true, message: '任务名称必输' },
                { max: 15, message: '任务名称最多允许输入15个字符' }
              ]}>
              <Input />
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col span={12}>
            <FormItem label='任务阶段' name='taskPhase' {...modalFormItemLayout} colon={colon}
              rules={[
                {required: true, message: '任务阶段必输' }
              ]}>
              <ASelect dataSource={taskPhaseData} onChange={taskPhaseOnChange}/>
            </FormItem>
          </Col>
          <Col span={12}>
            <FormItem label='任务起止时间' name='taskDate' {...modalFormItemLayout} colon={colon}
              rules={[
                {required: true, message: '任务起止时间必输' }
              ]}>
              <RangePicker format={dateFormatPattern} />
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col span={12}>
            <FormItem label='开发人员' name='developer' {...modalFormItemLayout} colon={colon}
              rules={[
                {required: true, message: '开发人员必输' }
              ]}>
              <ASelect dataSource={developerData} />
            </FormItem>
          </Col>
          <Col span={12}>
            <FormItem label='测试人员' name='tester' {...modalFormItemLayout} colon={colon}
              rules={[
                {required: true, message: '测试人员必输' }
              ]}>
              <ASelect dataSource={testerData} />
            </FormItem>
          </Col>
        </Row>
        <Row>
          <Col span={24}>
            <FormItem label='备注/附件CC路径' name='comment' {...maxModalFormItemLayout} colon={colon}
              rules={[
                { max: 100, message: '备注/附件CC路径最多允许输入100个字符' }
              ]}>
              <TextArea showCount maxLength={100} />
            </FormItem>
          </Col>
        </Row>
      </>
    );
  }

  const { modalTitle, modalWidth, modalVisible, loading, taskHandleLoading } = props;
  const code = 'trade-task';
  const rowKey = (record: TradeTaskItem) => `${record.taskId}-${record.taskHash}`;
  const pkField = 'taskHash';
  const buttonName = operaType === 'add' ? '新增任务': '修改任务';
  const localTradeTaskTotal = localTradeTaskList.length;
  const tradeTasks = fetchTaskByPage(1, pageSize, localTradeTaskList);

  return (
    <Modal
      title={modalTitle}
      destroyOnClose
      width={modalWidth}
      open={modalVisible}
      confirmLoading={loading}
      onOk={onOk}
      onCancel={onCancel}>
      <Form
        layout={formLayout}
        form={form}
        onFinish={addTaskToTable}
      >
        {
          getTaskContent(props)
        }
        <Row justify='center'>
          <Col>
            <FormItem>
              <Button type='primary' htmlType='submit' loading={taskHandleLoading}>{buttonName}</Button>
              <Button style={{ marginLeft: 8 }} onClick={onReset}>重置</Button>
            </FormItem>
          </Col>
        </Row>
      </Form>
      <Card title='任务列表' style={{ marginBottom: 0 }}>
        <AGrid
          code={code}
          actionColumnFixed={'right'}
          btnCallBack={handleBtnCallBack}
          columns={columns}
          rowKey={rowKey}
          pkField={pkField}
          dataSource={tradeTasks}
          loading={loading}
          total={localTradeTaskTotal}
          scroll={{x:1000}}
          onSelectRow={onSelectRow}
          onPageNumAndSizeChange={onPageNumAndSizeChange}
        />
      </Card>
    </Modal>
  );

}

export default TradeTaskModal;